import { AudioClip, AudioSource, Component, Node } from 'cc';

import CanvasExt from './CanvasExt';

/**
 * Cocos Creator 关于音效播放器的拓展
 */
export default class AudioExt {

    /**
     * 播放音效
     * @param clip 音效资源
     * @param stackable 是否允许同音效叠加
     * @param com 音效组件挂载父节点 (无参数则使用canvans)
     */
    static playAudioClip(clip: AudioClip, stackable: boolean = false, loop: boolean = false, com?: Component) {
        if (!clip || !clip.isValid)
            return;
        const parent: Node = !!com ? com.node : CanvasExt.canvasNode;
        if (!parent || !parent.isValid)
            return;

        let audioList: AudioSource[] = AudioExt.getAudioList(parent);
        // look for curent
        let curSource: AudioSource = null;
        for (const item of audioList) {
            if (item.clip.name == clip.name && (!stackable || item.currentTime <= 0)) {
                curSource = item;
                break;
            }
        }

        if (!curSource) {
            // create new
            let node = new Node();
            if (!node) return;
            let audioSource: AudioSource = node.addComponent(AudioSource);
            if (!audioSource) return;
            parent.addChild(node);
            audioSource.clip = clip;
            audioSource.volume = 1;
            audioSource.loop = loop;
            audioList.push(audioSource);
            curSource = audioSource;
        }

        parent.attr({ audioList });
        if (curSource)
            curSource.play();
    }
    /**
     * 停止播放指定音效
     * @param clip AudioClip | string
     * @param com 音效组件挂载父节点 (无参数则使用canvans)
     * @returns 
     */
    static stopAudioClip(clip: AudioClip | string, com?: Component) {
        if (!clip) return;
        const name: string = (clip instanceof AudioClip) ? clip.name : clip;
        if (!name) return;

        const parent: Node = !!com ? com.node : CanvasExt.canvasNode;
        if (!parent || !parent.isValid)
            return;

        AudioExt.getAudioList(parent).forEach(ad => {
            if (ad && ad.isValid && ad.clip.name == name)
                ad.stop();
        });
    }

    /**
     * 获取指定节点下的音效列表
     * @param node 
     * @returns 
     */
    static getAudioList(node: Node): AudioSource[] {
        let list: AudioSource[] = [];
        if (node && node.isValid)
            list = node['audioList'] as Array<AudioSource> || [];
        return list;
    }

}
